package coroutines.flow.operators

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import java.lang.Exception
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

class ProcessOperatorTest {
}

@InternalCoroutinesApi
fun main() {
    try {
        runBlocking(CoroutineExceptionHandler { coroutineContext: CoroutineContext, throwable: Throwable ->
            println("handleException{throwable = $throwable}")
        }) {
            launch {
                try {
                    flow {
                        for (i in 0..10) {
                            delay(100)
                            emit("emit $i")
                        }
                    }.onStart {
                        println("onStart{}")
                        println()
                    }
                        .onEach {
                            println()
                            println("onEach{$it}")

                            if (it == "emit 5") {
                                throw Exception("2233娘")
                            }
                        }
                        .onCompletion { cause ->
                            println()
                            println("onCompletion{cause = $cause}")
                        }
                        .onCompletion {
                            println()
                            println("onCompletion{}")
                        }
                            // 它的发送是collect的时机接受结果
                        .transform {
                            emit("[]")
                            ""
                        }.map{
                            it + it
                        }
                        .collect(object : FlowCollector<String> {
                            override suspend fun emit(value: String) {
                                println("collect{$value}")
                            }
                        })
                } catch (t:Throwable) {
                    println("in catch{t: $t}")
                }
            }
        }
    } catch (t: Throwable) {
        println("out catch{t: $t}")
    }
}